#include "pinyinhandler.h"
// 单例get
#include "configmanager.h"
#include "encryptutil.h"
#include "BaiduPinyinApi.h"
#include "OpenCCUtil.h"

#include <QDebug>
#include <QMutex>
#include <QTimer>
#include <algorithm>
#include <QSet>
#include <QFileInfo>
#include <QCoreApplication>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>

// 单独开辟封装一个工作线程类 拼音解析
class PinyinWorker : public QObject {
    Q_OBJECT
public:
    explicit PinyinWorker(PinyinHandler* handler) : m_handler(handler) {}
signals:
    void resultReady(const QVector<PinyinCandidate>& result);
public slots:
    void doWork(const QString& input) {
        QVector<PinyinCandidate> ans = m_handler->internalProcess(input);
        emit resultReady(ans);
    }
private:
    PinyinHandler* m_handler;
};

// #include "pinyinhandler.moc"
// =============================== PinyinHandler ==============================

PinyinHandler::PinyinHandler(QObject *parent)
  : QObject(parent), 
	m_pinyinType(FullPinyin), 
    m_fuzzyEnabled(true),
    m_isProcessing(false),
    m_useBaiduApi(true) // 默认开启百度API
{
	// init map
	initPinyinMap();

	m_doublePinyinScheme = ConfigManager::getInstance()->getValue(InputMethodGroup, "DoublePinyinScheme", "Sogou").toString();
	initDoublePinyinMap();

	// get from settings(come from ConfigManager)
	bool fuzzyEnabled = ConfigManager::getInstance()->getValue(InputMethodGroup, "FuzzyPinyin", true).toBool();
	setFuzzyPinyinEnabled(fuzzyEnabled);

	// work thread
	m_workerThread = new QThread(this);
	auto* worker = new PinyinWorker(this);
	worker->moveToThread(m_workerThread);

	// connect to slots
	connect(this, &PinyinHandler::processFinished, this, &PinyinHandler::onProcessFinished);
	connect(m_workerThread, &QThread::finished, worker, &QObject::deleteLater);
	connect(this, &PinyinHandler::destroyed, m_workerThread, &QThread::quit);
	connect(worker, &PinyinWorker::resultReady, this, &PinyinHandler::processFinished);  // 连接工作线程结果
	m_workerThread->start();

	// 初始化模糊音映射
	if (m_fuzzyMap.isEmpty()) {
        m_fuzzyMap["z"] = {"zh"};
        m_fuzzyMap["zh"] = {"z"};
        m_fuzzyMap["c"] = {"ch"};
        m_fuzzyMap["ch"] = {"c"};
        m_fuzzyMap["s"] = {"sh"};
        m_fuzzyMap["sh"] = {"s"};
    }

	// connect ConfigManager
	ConfigManager* config = ConfigManager::getInstance();
    connect(config, &ConfigManager::doublePinyinSchemeChanged, this, [this](const QString &scheme) {
        QMutexLocker locker(&m_doublePinyinMutex);
        if (m_doublePinyinScheme == scheme) return;
        m_doublePinyinScheme = scheme;
        initDoublePinyinMap();
        qInfo() << "[PinyinHandler] 双拼方案更新为：" << scheme;
    });
    connect(config, &ConfigManager::fuzzyPinyinChanged, this, [this](bool enabled) {
        if (m_fuzzyEnabled == enabled) return;
        setFuzzyPinyinEnabled(enabled);
        qInfo() << "[PinyinHandler] 模糊音状态更新为：" << (enabled ? "启用" : "禁用");
    });

    // init 联动 tool
    m_openccUtil = OpenCCUtil::getInstance();
    m_baiduApi = BaiduPinyinApi::getInstance();
    // 绑定百度API转换成功信号
    connect(m_baiduApi, &BaiduPinyinApi::conversionSuccess, this, &PinyinHandler::onBaiduConversionSuccess);
}

PinyinHandler::~PinyinHandler()
{
	// 析构就要阻塞一下工作线程
	m_workerThread->quit();
	m_workerThread->wait();
    qInfo() << "[PinyinHandler] 析构完成，工作线程已停止";
}

void PinyinHandler::setPinyinType(PinyinType type)
{
	m_pinyinType = type;
}

void PinyinHandler::setFuzzyPinyinEnabled(bool enabled)
{
	m_fuzzyEnabled = enabled;
}

void PinyinHandler::setFuzzyPinyinMap(const QMap<QString, QStringList> &fuzzyMap)
{
	m_fuzzyMap = fuzzyMap;
}

void PinyinHandler::processInput(const QString &input)
{
	QMutexLocker locker(&m_processMutex); // 确保 m_isProcessing 线程安全
    if (m_isProcessing) {
        qDebug() << "[PinyinHandler] 忽略重复输入：" << input << "（正在处理前一个请求）";
        return;
    }
    m_isProcessing = true;
    m_currentPinyin = input;

    if (input.isEmpty()) {
        reset();
        return;
    }

    // 容错：查找 Worker 实例，不存在则创建
    PinyinWorker* worker = m_workerThread->findChild<PinyinWorker*>();
    if (!worker) {
        qCritical() << "[PinyinHandler] 未找到 PinyinWorker，创建新实例";
        worker = new PinyinWorker(this);
        worker->moveToThread(m_workerThread);
        // 重新连接信号槽
        connect(worker, &PinyinWorker::resultReady, this, &PinyinHandler::processFinished);
        connect(m_workerThread, &QThread::finished, worker, &QObject::deleteLater);
    }

    // 异步调用 Worker（带返回值校验）
    bool invokeSuccess = QMetaObject::invokeMethod(
        worker, "doWork",
        Qt::QueuedConnection,
        Q_ARG(QString, input)
    );
    if (!invokeSuccess) {
        qCritical() << "[PinyinHandler] 异步调用 Worker 失败：" << input;
        m_isProcessing = false;
        emit invalidInput(input); // 触发无效输入信号，通知上层处理
    }
}

void PinyinHandler::reset()
{
	m_currentPinyin.clear();
    m_isProcessing = false;
}

QString PinyinHandler::currentPinyin() const
{
	return m_currentPinyin;
}

bool PinyinHandler::isProcessing() const
{
	return m_isProcessing;
}

bool PinyinHandler::loadBaseDictFromConfig()
{
	// get 单例实例
	ConfigManager* config = ConfigManager::getInstance();
	QString jsonPath = config->getValue(InputMethodGroup, "BaseDictPath").toString();
    bool encrypted = config->getValue(InputMethodGroup, "BaseDictEncrypted").toBool();

	// absolute --> relative
	QFileInfo fileInfo(jsonPath);
	if (!fileInfo.isAbsolute()) {
		// .exe + 相对的path
		jsonPath = QCoreApplication::applicationDirPath() + "/" + jsonPath;
	}
	// check 存在
	if (!QFile::exists(jsonPath)) {
		qWarning() << "[PinyinHandler] JSON 词库文件不存在：" << jsonPath;
        loadDefaultBaseDict(); // 加载兜底词库
        emit baseDictLoaded(false);
        return false;
	}
	// qt内置json load
	bool loadSuccess = loadBaseDictFromJSON(jsonPath, encrypted);
	if (!loadSuccess)	loadDefaultBaseDict();
	emit baseDictLoaded(loadSuccess);
	return loadSuccess;
}

//////////////////////////////////////////////////////////////////////
/// 汉字回拼音映射
QString PinyinHandler::getDefaultPinyinForChar(const QChar &ch)
{
	// 仅处理汉字（Unicode 范围：4E00-9FA5）
    if (ch.unicode() < 0x4E00 || ch.unicode() > 0x9FA5) {
        qDebug() << "[PinyinHandler] 非汉字字符不支持转拼音：" << ch;
        return "";
    }

    // 从反向映射表获取（首位为高频默认拼音）
    if (m_charToPinyinMap.contains(ch)) {
        const QStringList& pinyins = m_charToPinyinMap[ch];
        return pinyins.isEmpty() ? "" : pinyins.first();
    }

    qWarning() << "[PinyinHandler] 未找到汉字拼音：" << ch;
    return "";
}

QString PinyinHandler::convertTextToPinyin(const QString &text)
{
	QString result;
    for (const QChar& ch : text) {
        QString pinyin = getDefaultPinyinForChar(ch);
        if (!pinyin.isEmpty()) {
            result += pinyin + " "; // 多音节用空格分隔（如"编程"→"bian cheng "）
        } else {
            // 非汉字字符直接保留（如英文/数字）
            if (ch.isLetterOrNumber()) {
                result += ch.toLower();
            }
        }
    }
    return result.trimmed(); // 去除首尾空格
}

void PinyinHandler::setConvertDirection(OpenCCUtil::ConvertDirection dir)
{
    m_convertDir = dir;
    // 方向变更后重新解析当前拼音（触发候选词更新）
    if (!m_currentPinyin.isEmpty()) {
        processInput(m_currentPinyin);
    }
    qInfo() << "[PinyinHandler] 简繁转换方向更新为：" << static_cast<int>(dir);
}

void PinyinHandler::setUseBaiduApi(bool use)
{
    m_useBaiduApi = use;
    if (!use) {
        // 关闭时清空多音字缓存
        QMutexLocker locker(&m_polyphonicCacheMutex);
        m_polyphonicCache.clear();
    }
    qInfo() << "[PinyinHandler] 百度API使用状态更新为：" << (use ? "启用" : "禁用");
}

//////////////////////////////////////////////////////////////////////
void PinyinHandler::onProcessFinished(const QVector<PinyinCandidate> &candidates) {
	m_isProcessing = false;
	if (candidates.isEmpty()) {
		if (isPrefixOfAnyPinyin(m_currentPinyin))	emit inputIncomplete(m_currentPinyin);
		else										emit invalidInput(m_currentPinyin);
	}		
	else											emit candidatesGenerated(candidates);
}

void PinyinHandler::onBaiduConversionSuccess(const QString &text, const QString &pinyin)
{
    if (text.isEmpty() || pinyin.isEmpty())     return;

    // 更新多音字缓存
    QMutexLocker locker(&m_polyphonicCacheMutex);
    m_polyphonicCache[text] = pinyin;
    locker.unlock();

    // 重新解析当前拼音（触发候选词更新）
    if (!m_currentPinyin.isEmpty()) {
        processInput(m_currentPinyin);
    }
    qInfo() << "[PinyinHandler] 百度API获取多音字拼音成功：" << text << "→" << pinyin;
}

// 核心处理逻辑
QVector<PinyinCandidate> PinyinHandler::internalProcess(const QString &input)
{
    QVector<PinyinCandidate> candidates;
	// 根据类型来解析
	switch (m_pinyinType) {
    case FullPinyin:
        candidates = parseFullPinyin(input);
        break;
    case DoublePinyin:
        candidates = parseDoublePinyin(input);
        break;
    case SimplePinyin:
        candidates = parseSimplePinyin(input);
        break;
    default:
        candidates = parseFullPinyin(input);
    }
    // 多音节 调用百度APi
    if (m_useBaiduApi && !candidates.isEmpty()) {
        QVector<PinyinCandidate> correctedCandidates;
        for (auto& cand : candidates) {
            // 对多字词语（如“重庆”）获取精准拼音
            if (cand.text.length() > 1) {
                QString polyPinyin = getPolyphonicPinyinFromBaidu(cand.text);
                if (!polyPinyin.isEmpty()) {
                    cand.pinyin = polyPinyin; // 用百度API返回的拼音替换原拼音
                }
            }
            correctedCandidates.append(cand);
        }
        candidates = correctedCandidates;
    }

    // 根据cur direction  转换候选词简繁
    candidates = convertCandidatesSimplifiedTraditional(candidates);
    // 去重 排序
    QSet<PinyinCandidate> uniqueSet(candidates.begin(), candidates.end());
    candidates = QVector<PinyinCandidate>(uniqueSet.begin(), uniqueSet.end());
    std::sort(candidates.begin(), candidates.end());

    return candidates;
}

QVector<PinyinCandidate> PinyinHandler::parseFullPinyin(const QString &pinyin)
{	
	// check pinyin 在map？
	QVector<PinyinCandidate> ans;
	// 应用模糊音
    QStringList fuzzyPinyins = m_fuzzyEnabled ? applyFuzzyPinyin(pinyin) : QStringList{pinyin};
	// 组合一下
	foreach (const QString& fuzzy, fuzzyPinyins) {
		// 分割多音节
		QStringList syllables = splitPinyinSyllables(fuzzy);
		if (syllables.isEmpty()) continue;

		// 单音节直接匹配
		if (syllables.size() == 1) {
			if (m_pinyinMap.contains(syllables[0])) ans += m_pinyinMap[syllables[0]];
		}
		// 多音节直接组合
		else {
			QString combinedKey = syllables.join(" ");
			if (m_pinyinMap.contains(combinedKey))	ans += m_pinyinMap[combinedKey];
		}
	}
	// 词频 去重排序
	QSet<PinyinCandidate> uniqueSet(ans.begin(), ans.end());
    ans = QVector<PinyinCandidate>(uniqueSet.begin(), uniqueSet.end());
	std::sort(ans.begin(), ans.end());
	return ans;
}

// 双拼解析
QVector<PinyinCandidate> PinyinHandler::parseDoublePinyin(const QString &pinyin)
{
	QMutexLocker locker(&m_doublePinyinMutex); // 加锁保护双拼映射表读取
	// 双拼
	QString fullPinyin;
	for (QChar c : pinyin) {
		if (m_doublePinyinMap.contains(c))	fullPinyin += m_doublePinyinMap[c];
		else {
			qWarning() << "[PinyinHandler] 双拼字符未找到映射：" << c << "（方案：" << m_doublePinyinScheme << "）";
			return {};
		}
	}
	qDebug() << "[PinyinHandler] 双拼解析完成：" << pinyin << "→" << fullPinyin << "（方案：" << m_doublePinyinScheme << "）";
	return parseFullPinyin(fullPinyin);
}

// 简拼
QVector<PinyinCandidate> PinyinHandler::parseSimplePinyin(const QString &pinyin)
{
	// 预分配内存 提高性能 
	QVector<PinyinCandidate> ans;
	ans.reserve(1000);

	// 提取音节首字母 ni hao --> nh
	foreach (const auto& key, m_pinyinMap.keys()) {
		QStringList syllables = key.split(" ");
        QString firstLetters;
		foreach (const QString& syl, syllables) {
            if (!syl.isEmpty()) firstLetters += syl[0];
        }
		// 简拼匹配
		if (firstLetters.startsWith(pinyin))	ans += m_pinyinMap[key];
	}

	// 去重截断 
	
	// // 去重  但是感觉直接用set不太行
	// if (!ans.empty()) {
	// 	auto last = ans.begin();
	// 	for (auto first = ans.begin() + 1; first != ans.end(); first++) {
	// 		if (first->text != last->text) {
	// 			++last;
	// 			*last = *first;
	// 		}
	// 	}
	// 	ans.erase(++last, ans.end());
	// }
	QSet<PinyinCandidate> uniqueSet(ans.begin(), ans.end());

	// 性能提高part
	// 如果结果过大，先截断再排序以提高性能
	const int MAX_RESULTS = 1000; // 根据需求调整最大结果数
    if (ans.size() > MAX_RESULTS)		ans.resize(MAX_RESULTS);

	std::sort(ans.begin(), ans.end());
	return ans;
}

// 模糊音处理（支持中间字符替换）····
QStringList PinyinHandler::applyFuzzyPinyin(const QString &pinyin)
{
	QSet<QString> result;
    result.insert(pinyin);  // 保留原拼音

    // 替换所有可能的模糊映射（不仅开头）
    foreach (const QString& pattern, m_fuzzyMap.keys()) {
        int pos = 0;
        while ((pos = pinyin.indexOf(pattern, pos)) != -1) {
            foreach (const QString& replacement, m_fuzzyMap[pattern]) {
                QString fuzzy = pinyin;
                fuzzy.replace(pos, pattern.length(), replacement);
                result.insert(fuzzy);
            }
            pos += pattern.length();
        }
    }
	return QStringList(result.values());
}

// 从json中加载
void PinyinHandler::initPinyinMap()
{
	loadBaseDictFromConfig(); 
	// 单音节加载 

	// 多音节加载 

	// 收集所有单音节来校验
}

// 双拼表映射初始化 
void PinyinHandler::initDoublePinyinMap()
{
	m_doublePinyinMap.clear();
    qInfo() << "[PinyinHandler] 初始化双拼方案：" << m_doublePinyinScheme;

	///////////////////////////////////////////////////////////////////////////// 
	// 搜狗双拼映射
	QMap<QChar, QString> sogouConsonantMap = {
        {'b', "b"}, {'p', "p"}, {'m', "m"}, {'f', "f"}, {'d', "d"}, {'t', "t"},
        {'n', "n"}, {'l', "l"}, {'g', "g"}, {'k', "k"}, {'h', "h"}, {'j', "j"},
        {'q', "q"}, {'x', "x"}, {'v', "zh"}, {'i', "ch"}, {'u', "sh"}, {'r', "r"},
        {'z', "z"}, {'c', "c"}, {'s', "s"}, {'w', "w"}, {'y', "y"}
    };

    // 搜狗双拼：韵母映射（完整覆盖所有常用韵母）
    QMap<QChar, QString> sogouVowelMap = {
        {'a', "a"}, {'o', "o"}, {'e', "e"}, {'i', "i"}, {'u', "u"}, {'v', "ü"},
        {'l', "ai"}, {'f', "ei"}, {'d', "ui"}, {'k', "ao"}, {'p', "ou"}, {'q', "iu"},
        {'x', "ie"}, {'t', "üe"}, {'r', "er"}, {'j', "an"}, {'n', "en"}, {'m', "in"},
        {'b', "un"}, {'v', "ün"}, {'h', "ang"}, {'g', "eng"}, {'y', "ing"}, {'s', "ong"},
        {'w', "uo"}, {'c', "ian"}, {'s', "iong"}, {'z', "uan"}, {'h', "uang"}, {'g', "iang"}
    };
	///////////////////////////////////////////////////////////////////////////// 
	// Microsoft双拼映射
	QMap<QChar, QString> microsoftConsonantMap = {
        {'b', "b"}, {'p', "p"}, {'m', "m"}, {'f', "f"}, {'d', "d"}, {'t', "t"},
        {'n', "n"}, {'l', "l"}, {'g', "g"}, {'k', "k"}, {'h', "h"}, {'j', "j"},
        {'q', "q"}, {'x', "x"}, {'a', "zh"}, {'s', "ch"}, {'d', "sh"}, {'r', "r"},
        {'z', "z"}, {'c', "c"}, {'s', "s"}, {'w', "w"}, {'y', "y"}
    };
    QMap<QChar, QString> microsoftVowelMap = {
        {'a', "a"}, {'o', "o"}, {'e', "e"}, {'i', "i"}, {'u', "u"}, {'v', "ü"},
        {'k', "ai"}, {'l', "ei"}, {'r', "ui"}, {'h', "ao"}, {'p', "ou"}, {'q', "iu"},
        {'j', "ie"}, {'x', "üe"}, {'e', "er"}, {'f', "an"}, {'g', "en"}, {'y', "in"},
        {'t', "un"}, {'v', "ün"}, {'s', "ang"}, {'d', "eng"}, {'w', "ing"}, {'f', "ong"},
        {'z', "uo"}, {'c', "ian"}, {'t', "iong"}, {'w', "uan"}, {'r', "uang"}, {'q', "iang"}
    };
	///////////////////////////////////////////////////////////////////////////// 

    // 合并声母+韵母映射（搜狗方案）
    if (m_doublePinyinScheme == "Sogou") {
		m_doublePinyinMap = sogouConsonantMap;
		m_doublePinyinMap.insert(sogouVowelMap);
		qInfo() << "[PinyinHandler] 加载搜狗双拼映射：" << m_doublePinyinMap.size() << "个字符映射";
    } else if (m_doublePinyinScheme == "Microsoft") { // 新增微软方案分支
		m_doublePinyinMap = microsoftConsonantMap;
		m_doublePinyinMap.insert(microsoftVowelMap);
        qInfo() << "[PinyinHandler] 加载微软双拼映射：" << m_doublePinyinMap.size() << "个字符映射";
    } else {
        // 其他方案默认降级为搜狗（可扩展微软/谷歌）
		qWarning() << "[PinyinHandler] 未知双拼方案：" << m_doublePinyinScheme << "，默认使用搜狗双拼";
		m_doublePinyinMap = sogouConsonantMap;
		m_doublePinyinMap.insert(sogouVowelMap);
		qInfo() << "[PinyinHandler] 默认加载搜狗双拼映射：" << m_doublePinyinMap.size() << "个字符映射";
    }

    qInfo() << "[PinyinHandler] 双拼映射加载完成：" << m_doublePinyinMap.size() << "个字符映射";
}

// 贪心算法（从后往前匹配最长有效音节
QStringList PinyinHandler::splitPinyinSyllables(const QString &pinyin)
{
	QStringList ans;
	// 边界校验  null or noInit
	if (pinyin.isEmpty() || m_allSyllables.isEmpty()) {
		qWarning() << "[PinyinHandler] 音节拆分失败：输入为空或单音节集合未加载";
        return ans;
	}

	// 单引号作为隔音符 split
	QStringList segments = pinyin.split('\'', Qt::SkipEmptyParts);
	if (segments.isEmpty()) {
		qWarning() << "[PinyinHandler] 音节拆分失败：输入仅含隔音符";
        return ans;
	}
	// 贪心拆解  从后往前匹配最长有效音节
	for (const QString& segment : segments) {
		QStringList segmentAns;
		int segmentLen = segment.length();
		int startIdx = 0;	// 当前分段的起始位置

		while (startIdx < segmentLen) {
			bool found = false;
			// try match 最长可能的音节
			int maxMatchLen = qMin(startIdx + 6, segmentLen);
			for (int endIdx = maxMatchLen; endIdx > startIdx; endIdx--) {
				// 子串 
				QString subPinyin = segment.mid(startIdx, endIdx - startIdx);
				// cheak  留下有效单音节 不区分大小写 依赖 json 的m_allSyllables
				if (m_allSyllables.contains(subPinyin.toLower())) {
					segmentAns.prepend(subPinyin.toLower());	// 往前插入 顺序保证
					startIdx = endIdx;
					found = true;
					break;
				}
			}
			// 容错 避免崩溃 找不到有效就回空音节
			if (!found) {
				QString invalidPart = segment.mid(startIdx);
				qWarning() << "[PinyinHandler] 音节拆分失败：无效音节" << invalidPart << "（完整输入：" << pinyin << "，当前分段：" << segment << "）";
			}
		}
		// 合并
		ans.append(segmentAns);
	}
	qDebug() << "[PinyinHandler] 音节拆分完成：" << pinyin << "→" << ans.join(" ");
	return ans;
}

bool PinyinHandler::isPrefixOfAnyPinyin(const QString &prefix)
{
	// 判断输入是否为某个单音节拼音的前缀（用于区分“不完整输入”和“无效输入”）
	if (prefix.isEmpty() || m_allSyllables.isEmpty())	return false;
	// foreach 所有单音节
	for (const auto& syllable : m_allSyllables) {
		if (syllable.startsWith(prefix, Qt::CaseInsensitive))	return true;
	}
	return false;
}

// 内部json词库load
bool PinyinHandler::loadBaseDictFromJSON(const QString &jsonPath, bool encrypted)
{
	// 直接使用原始JSON路径，无需临时文件
    QFile jsonFile(jsonPath);
    if (!jsonFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "[PinyinHandler] JSON 文件打开失败：" << jsonFile.errorString();
        return false;
    }

    // 读取并解析JSON
    QByteArray jsonData = jsonFile.readAll();
    jsonFile.close();

    QJsonParseError parseErr;
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData, &parseErr);
    if (parseErr.error != QJsonParseError::NoError) {
        qWarning() << "[PinyinHandler] JSON 解析失败: " << parseErr.errorString() 
                   << "（位置: " << parseErr.offset << "）";
        return false;
    }

    // 清空现有缓存
    m_pinyinMap.clear();
    m_allSyllables.clear();
    QJsonObject rootObj = jsonDoc.object();

    // 加载单音节词
    if (rootObj.contains("single_syllables")) {
        QJsonObject singleObj = rootObj["single_syllables"].toObject();
        for (auto it = singleObj.begin(); it != singleObj.end(); ++it) {
            QString pinyin = it.key();
            QJsonArray candArr = it.value().toArray();
            QVector<PinyinCandidate> candidates;

            for (const QJsonValue& val : candArr) {
                QJsonObject candObj = val.toObject();
                QString text = candObj["text"].toString();
                int frequency = candObj["frequency"].toInt(1);
                bool isUserWord = candObj["isUserWord"].toBool(false);

                if (!text.isEmpty()) {
                    candidates.append({text, frequency, pinyin, isUserWord});
                }
            }

            if (!candidates.isEmpty()) {
                m_pinyinMap[pinyin] = candidates;
                m_allSyllables.insert(pinyin); // 加入单音节集合用于校验
            }
        }
    }

    // 加载多音节词
    if (rootObj.contains("multi_syllables")) {
        QJsonObject multiObj = rootObj["multi_syllables"].toObject();
        for (auto it = multiObj.begin(); it != multiObj.end(); ++it) {
            QString pinyin = it.key();
            QJsonArray candArr = it.value().toArray();
            QVector<PinyinCandidate> candidates;

            for (const QJsonValue& val : candArr) {
                QJsonObject candObj = val.toObject();
                QString text = candObj["text"].toString();
                int frequency = candObj["frequency"].toInt(1);
                bool isUserWord = candObj["isUserWord"].toBool(false);

                if (!text.isEmpty()) {
                    candidates.append({text, frequency, pinyin, isUserWord});
                }
            }

            if (!candidates.isEmpty()) {
                m_pinyinMap[pinyin] = candidates;
            }
        }
    }

    // 构建汉字到拼音的反向映射
    initCharToPinyinMap();

    qInfo() << "[PinyinHandler] JSON 词库加载成功：" 
            << "单音节词" << m_allSyllables.size() << "个" 
            << "总候选词映射" << m_pinyinMap.size() << "条";
    return true;
}

void PinyinHandler::loadDefaultBaseDict()
{
	qWarning() << "[PinyinHandler] 加载内置默认词库（主词库加载失败）";
	// 清空原有缓存
    m_pinyinMap.clear();
    m_allSyllables.clear();

	// 两种的内置 
	QVector<PinyinCandidate> aCandidates = {
        {"啊", 120, "a", false},
        {"阿", 90, "a", false}
    };
    m_pinyinMap["a"] = aCandidates;
    m_allSyllables.insert("a");
    QVector<PinyinCandidate> bianCandidates = {
        {"编", 100, "bian", false},
        {"边", 95, "bian", false}
    };
    m_pinyinMap["bian"] = bianCandidates;
    m_allSyllables.insert("bian");

	QVector<PinyinCandidate> bianChengCandidates = {
        {"编程", 85, "bian cheng", false}
    };
    m_pinyinMap["bian cheng"] = bianChengCandidates;

    qInfo() << "[PinyinHandler] 内置默认词库加载完成：" << m_pinyinMap.size() << "条映射";
}

void PinyinHandler::initCharToPinyinMap()
{
	// TODO  构建反向映射 汉字到拼音
	m_charToPinyinMap.clear();
    for (auto it = m_pinyinMap.begin(); it != m_pinyinMap.end(); ++it) {
        QString pinyin = it.key();
        const QVector<PinyinCandidate>& candidates = it.value();

        for (const auto& cand : candidates) {
            QChar ch = cand.text.at(0); // 暂只处理单字（多字可后续扩展）
            if (!m_charToPinyinMap.contains(ch)) {
                m_charToPinyinMap[ch] = QStringList();
            }
            if (!m_charToPinyinMap[ch].contains(pinyin)) {
                m_charToPinyinMap[ch].append(pinyin);
            }
        }
    }
    qInfo() << "[PinyinHandler] 汉字→拼音反向映射构建完成：" << m_charToPinyinMap.size() << "个汉字";
}

QVector<PinyinCandidate> PinyinHandler::convertCandidatesSimplifiedTraditional(const QVector<PinyinCandidate> &candidates)
{
	if (!m_openccUtil || !m_openccUtil->isInitialized() || candidates.isEmpty()) {
        return candidates;
    }

    QVector<PinyinCandidate> convertedCandidates;
    for (const auto& cand : candidates) {
        // 调用OpenCCUtil转换候选词文本
        QString convertedText = m_openccUtil->convert(cand.text, m_convertDir);
        if (convertedText.isEmpty()) {
            convertedText = cand.text; // 转换失败则保留原文本
        }
        // 构造转换后的候选词（拼音不变，文本更新）
        PinyinCandidate convertedCand = cand;
        convertedCand.text = convertedText;
        convertedCandidates.append(convertedCand);
    }

    qDebug() << "[PinyinHandler] 候选词简繁转换完成，原数量：" << candidates.size() << "，转换后数量：" << convertedCandidates.size();
    return convertedCandidates;
}

QString PinyinHandler::getPolyphonicPinyinFromBaidu(const QString &word)
{
	if (!m_useBaiduApi || !m_baiduApi || word.isEmpty()) {
        return "";
    }

    // 1. 优先从缓存获取
    QMutexLocker locker(&m_polyphonicCacheMutex);
    if (m_polyphonicCache.contains(word)) {
        return m_polyphonicCache.value(word);
    }
    locker.unlock();

    // 2. 调用百度API转换（异步）
    m_baiduApi->convertToPinyin(word);
    // 此处不阻塞，等待onBaiduConversionSuccess回调更新缓存后再使用
    // 临时返回空，后续通过信号重新触发候选词生成
    return "";
}
